package com.invengo.module_check.ui.fragment.select_layer;

import android.app.Application;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.invengo.base.utils.BeanMapperUtils;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.ShelfBean;

import me.goldze.mvvmhabit.http.UpdateResult;

import com.invengo.library_rfid.classify.RFIDCallBackListener;
import com.invengo.module_check.data.entity.ActionArgs;
import com.invengo.module_check.data.repsitory.business.BusinessRepsitory;
import com.invengo.library_rfid.classify.AnalyzeImpl;
import com.invengo.library_rfid.entity.TagInfo;

import java.util.List;

import io.reactivex.Observable;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.http.BaseBean;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.StringUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;

/**
 * 废弃，使用SelectShelfUtils 来选层架
 */
public class SelectLayerViewModel extends BaseViewModel<BusinessRepsitory> {
    public RFIDCallBackListener rfidService = new RFIDCallBackListener(AnalyzeImpl.TO_SHELF, tagInfo -> onScanResult(tagInfo), state -> {
        isReading.set(state);
        if (!state)
            cleanRFIDCacheNotStop();
    });
    public SingleLiveEvent<Boolean> showSupport = new SingleLiveEvent<>();
    private ActionArgs actionArgs;
    private List<BookBean> bookBeans;

    public void setArgements(ActionArgs actionArgs, List<BookBean> bookBeans) {
        this.actionArgs = actionArgs;
        this.bookBeans = bookBeans;
    }

    public ShelfBean shelfBean;
    public SingleLiveEvent<String> shelfName = new SingleLiveEvent<>();
    public SingleLiveEvent<String> shelfCode = new SingleLiveEvent<>();
    public SingleLiveEvent<Integer> bookSize = new SingleLiveEvent<>();

    public SelectLayerViewModel(@NonNull Application application) {
        super(application, BusinessRepsitory.getInstance());
        registerRFID(rfidService);

    }

    public UIChangeObservable ui = new UIChangeObservable();


    public class UIChangeObservable {
        public SingleLiveEvent<ShelfBean> listingEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ShelfBean> inventoryEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ShelfBean> parallelEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ShelfBean> firstPosEvent = new SingleLiveEvent<>();

        public SingleLiveEvent<List<BookBean>> forcePosEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<List<BookBean>> changeShelfEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<Integer> codeLengthEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ShelfBean> selectShelfEvent = new SingleLiveEvent<>();


    }

    //    @Override
    public void onScanResult(TagInfo tagInfo) {
        switch (tagInfo.getRfidModel()) {
            case TID:
                getShelfByTid(tagInfo.getTag());
                break;
            case EPC:
            case U_DATA:
                getShelfByCode(tagInfo.getTag());
                break;
        }
    }

    /**
     * 按tid取架
     *
     * @param tid 时间
     */
    private void getShelfByTid(String tid) {
        model.getShelfInfoByTid(tid)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bean -> updateShelf(bean));
    }

    /**
     * 查询货架信息
     *
     * @param code 标签
     */
    private void getShelfByCode(String code) {
        if (StringUtils.isEmpty(code))
            return;
        model.getShelfInfoByCode(code)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bean -> updateShelf(bean));
    }


    public BindingCommand conform = new BindingCommand(() -> {
        if (TextUtils.isEmpty(shelfCode.getValue()) | TextUtils.isEmpty(shelfName.getValue())) {
            Looper.prepare();
            ToastUtils.showShort("请先扫描或输入层架！");
            Looper.loop();
            return;
        }
        switch (actionArgs) {
            case ACTION_FORCE:
                forcePositioning();
                break;
            case ACTION_CHANGE:
                changeShelf();
                break;
            case ACTION_LISTING:
                if (shelfBean == null) {
                    getShelfByCode(shelfCode.getValue());
                    return;
                }
                ui.listingEvent.postValue(shelfBean);
                break;
            case ACTION_INVENTORY:
                if (shelfBean == null) {
                    getShelfByCode(shelfCode.getValue());
                    return;
                }
                ui.inventoryEvent.postValue(shelfBean);
                break;
            case ACTION_PARALLEL:
                if (shelfBean == null) {
                    getShelfByCode(shelfCode.getValue());
                    return;
                }
                ui.parallelEvent.postValue(shelfBean);
                break;
            case ACTION_FIRST:
                if (shelfBean == null) {
                    getShelfByCode(shelfCode.getValue());
                    return;
                }
                ui.firstPosEvent.postValue(shelfBean);
                break;

        }
    });

    private void changeShelf() {
        Observable<BaseBean<UpdateResult>> dataObservable = model.changeShelf(bookBeans, shelfCode.getValue(), shelfName.getValue());
        Observable<BaseBean<UpdateResult>> logObservable = model.changeShelfLog(BeanMapperUtils.cloneList(bookBeans), shelfCode.getValue());
        Observable.merge(dataObservable, logObservable)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(updateResult -> {
                }, throwable -> {
                    ui.changeShelfEvent.postValue(null);
                }, () -> {
                    getUC().getHideKeyboardEvent().call();
                    for (BookBean bookBean : bookBeans) {
                        bookBean.setShelfCode(shelfCode.getValue());
                        bookBean.setShelfName(shelfName.getValue());
                    }
                    ui.changeShelfEvent.postValue(bookBeans);
                });
    }

    public BindingCommand cleanCache = new BindingCommand(() -> {
        cleanRFIDCacheNotStop();
        shelfName.postValue(null);
        shelfCode.postValue(null);
        shelfBean = null;
    });

    private void forcePositioning() {
        model.forcePositioning(bookBeans, shelfCode.getValue(), shelfName.getValue())
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(updateResult -> {
                    ui.forcePosEvent.postValue(bookBeans);
                }, throwable -> {
                    ui.forcePosEvent.postValue(null);
                });
    }

    /**
     * 下一个货架
     */
    public BindingCommand nextShelf = new BindingCommand(() -> {
        stopScan();
        model.getNextOrUpperShelf(shelfCode.getValue(), false)
                .compose(RxUtils.applySchedulersLoading(getLifecycleProvider(), this))
                .subscribe(bean -> updateShelf(bean));
    });
    /**
     * 前一个货架
     */
    public BindingCommand preShelf = new BindingCommand(() -> {
        stopScan();
        model.getNextOrUpperShelf(shelfCode.getValue(), true)
                .compose(RxUtils.applySchedulersLoading(getLifecycleProvider(), this))
                .subscribe(bean -> updateShelf(bean));
    });

    //  2023/11/30 这里是个bug，临时方法处理下
    public void newLive() {
        shelfName = new SingleLiveEvent<>();
        shelfCode = new SingleLiveEvent<>();
        bookSize = new SingleLiveEvent<>();
    }


    public void updateShelf(ShelfBean bean) {
        new Thread(() -> {
            shelfName.postValue(bean.getShelfName());
            shelfCode.postValue(bean.getShelfCode());
            shelfBean = bean;
            if (!ACache.getInstance().getAsBoolean(AKey.AUTO_SCAN_SHELF_LAUNCH))
                return;
            switch (actionArgs) {
                case ACTION_LISTING:
                case ACTION_INVENTORY:
                case ACTION_PARALLEL:
                case ACTION_FIRST:
                    conform.execute();
                    break;
            }
//            getBookByShelfCode(bean.getShelfCode());
        }).start();
    }

    public BindingCommand<String> textChangeCommand = new BindingCommand<>(s -> {
        getUC().getHideKeyboardEvent().call();
        getShelfByCode(s);
        ui.codeLengthEvent.postValue(s.length());
    });
    public BindingCommand selectShelf = new BindingCommand<>(() -> {
        ui.selectShelfEvent.postValue(shelfBean);
    });
}
